Production-ready FastAPI template with modular architecture, async stack, Celery, and full Docker setup.
- Async FastAPI with modular domain structure.
- DB via SQLAlchemy async, repositories + Unit of Work for transactional work.
- Caching: Redis cache layer (
src/core/redis/*) with tags, decorators, lifecycle helpers, and deterministic ETag support for route responses. - Rate limiting: limiter package (
src/core/limiter) with FastAPI dependencies (both IP and user-based). - Messaging: Celery workers/beat + RabbitMQ broker.
- Edge: Nginx reverse proxy with WebSocket upgrade headers.
- Email service: templated mailer with Celery tasks for async sending.
- Auth & JWT: user module with auth usecases, tokens, permissions.
- Storage: async S3 adapter (
src/core/storage/s3) with presign support. - Observability/resilience: structured logging (loggers), retry utils, health route.
- Type safety: mypy in strict mode; strict settings (no implicit Optional, no untyped defs, disallow Any in generics) keep interfaces honest and catch regressions early.
- Tooling: pre-commit/ruff/black/mypy, pytest (asyncio), Alembic migrations.
- Primary rate limiting uses Redis-backed
RateLimiterdependencies fromsrc/core/limiter. - If Redis is temporarily unavailable, the limiter falls back to an in-memory per-process window so protection still works in degraded mode.
- Be careful in multi-instance deployments: this fallback is not distributed, so each instance enforces its own local counter and the effective global limit becomes higher than the configured value.
- Even with that limitation, the fallback is still useful because requests remain best-effort rate-limited instead of becoming completely unlimited during a Redis outage.
- CI runs a dedicated security job in
.github/workflows/ci.yml. banditscans application, migration, and script code for insecure patterns.pip-auditchecks pinned filesinfra/requirements/base.txt,infra/requirements/dev.txt, andinfra/requirements/prod.txtfor known vulnerable packages.gitleaksscans the repository for committed secrets.gitleakskeeps history scanning enabled and uses a repo allowlist only for known example/test placeholders.pip-auditcurrently ignoresCVE-2026-4539explicitly becausepygments==2.19.2is present in the dev graph and no fix version is reported yet.- These checks are intended to fail the pipeline on real findings, so dependency updates should keep the pinned requirement files current.
- Install Docker and Docker Compose, Python 3.13 (for local scripts/hooks).
- Copy env:
cp .env.example .envand fill required values. For tests you can also use.env.test(picked up whenTESTING=truein env). - Dev with reload:
make run-dev(Nginx on 8000, app on 8001). - Prod-like:
make run. - Stop:
make down; logs:make logs; tests:make test/make test-cov; lint:make lint.
- Application tests mirror
src/undertests/unit/src/. - Shared test infrastructure lives in
tests/conftest.py,tests/helpers/,tests/fakes/, andtests/factories/. - Reserve
tests/integration/src/for integration coverage when a scenario requires more than unit-level wiring. - Run a focused file with
TESTING=true pytest tests/unit/src/<module>/test_<name>.py.
- Nginx: 8000 → app:8001
- App direct: 8001
- Postgres: 5432
- Redis: 6379
- RabbitMQ: 5672 (AMQP), 15672 (UI)
- API docs: http://localhost:8000/docs (or http://localhost:8001/docs directly)
- Health: http://localhost:8001/health/
make run-dev— build+up with override (reload)make run— build+up prod-likemake migrate/make migration— apply/create Alembic revisionsmake logs/make logs-app— view logsmake clean— remove containers/volumes/images/orphansmake lint/make test— quality checksmake test-cov— tests with coverage report
- Install dev deps:
pip install -r infra/requirements/dev.txt - Update hooks:
pre-commit autoupdate(and commit.pre-commit-config.yamlchanges) - Clean hook envs if needed:
pre-commit clean - Run all hooks locally:
pre-commit run --all-filesormake lint
- Install tools:
pip install bandit pip-audit - Static scan:
bandit -r src scripts migrations -q - Dependency audit:
pip-audit --ignore-vuln CVE-2026-4539 -r infra/requirements/base.txt -r infra/requirements/dev.txt -r infra/requirements/prod.txt - Secret scan:
gitleaks detect --source .
- Source files:
infra/requirements/*.incontain direct dependencies (typically without pins). - Lockfiles:
infra/requirements/*.txtare generated bypip-compile. - Update lockfiles:
make req-compile - Sync environment:
make req-sync-dev/make req-sync-prod - When needed, add pins or ranges in
.in(e.g.fastapi>=0.110,<1) and recompile. make req-compilerunspip-compileinsidepython:3.13-slim-bookwormwithlinux/amd64by default to keep lockfiles close to production.- Override the target platform when needed, for example
make req-compile REQ_COMPILE_PLATFORM=linux/arm64.
- Architecture & structure: docs/readme/architecture.md
- Infrastructure & ops: docs/readme/infra.md
- Contributing & CI/CD: docs/readme/contributing.md